package net.sf.rose.business.bean.database;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import net.sf.rose.exception.SystemErrorCode;
import net.sf.rose.exception.SystemException;
import net.sf.rose.jdbc.service.DataBaseFactory;

import org.apache.log4j.Logger;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;

/**
 * @author fengjian
 * @since 2014-6-12
 */
@Root(name = "table")
public class TableMetaBean implements Serializable {

	private static final long serialVersionUID = 1L;

	private static Logger logger = Logger.getLogger(TableMetaBean.class);

	/** 表名称 */
	@Attribute
	private String name = null;

	/** 表说明 */
	@Attribute(required = false)
	private String text = null;

	/** 主键策略 */
	@Attribute(required = false)
	private String keyGenerate = null;

	/** 表描述 */
	@Attribute(required = false)
	private String description = null;

	/** 字段列表 */
	@ElementList(required = false)
	private List<FieldMetaBean> fields = null;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public String getKeyGenerate() {
		return keyGenerate;
	}

	public void setKeyGenerate(String keyGenerate) {
		if (!keyGenerate.trim().equals("")) {
			this.keyGenerate = keyGenerate;
		}
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public List<FieldMetaBean> getFields() {
		return fields;
	}

	public void setFields(List<FieldMetaBean> fields) {
		this.fields = fields;
	}

	public void addField(FieldMetaBean field) {
		if (this.fields == null) {
			this.fields = new ArrayList<FieldMetaBean>();
		}
		this.fields.add(field);
	}

	/**
	 * 根据字段名称返回字段定义类
	 * @param name 	- 字段名称
	 */
	public FieldMetaBean getFieldBean(String name) {
		for (FieldMetaBean f : this.fields) {
			if (f.getName().equals(name)) {
				return f;
			}
		}
		return null;
	}

	/**
	 * 返回表的主键字段定义类
	 */
	public FieldMetaBean getPKFieldBean() {
		for (FieldMetaBean f : this.fields) {
			if (f.isPk()) {
				return f;
			}
		}
		return null;
	}

	private KeyGenerator keyGenerator = null;

	/**
	 * 生成主键
	 * @return - 主键
	 */
	public String getUID() {
		if(this.keyGenerator == null){
			this.keyGenerator = new KeyGenerator();
			this.keyGenerator.setkeyGenerateString(keyGenerate);
			// 如果需要初始化计数器
			if (this.keyGenerator.isNeedInitialCount()) {
				String fieldName = this.getPKFieldBean().getName();
				String sql = "select max(" + fieldName + ") from " + this.name;
				Connection con = null;
				try {
					con = DataBaseFactory.getService().getConnection();
					ResultSet results = con.createStatement().executeQuery(sql);
					if (results.next()) {
						Object obj = results.getObject(1);
						if (obj != null) {
							String key = obj.toString();
							this.keyGenerator.initialCount(key);
							String mess = "表(" + this.name + ")的主键(" + fieldName + ")生成策略开始于：";
							logger.warn(mess + this.keyGenerator.getUID());
							this.keyGenerator.backCount();
						}
					}
				} catch (SQLException e) {
					String message = "从数据库表中查找初始计数器元数据查找失败！";
					logger.error("sql:" + sql);
					logger.error(message, e);
					throw new SystemException(message, SystemErrorCode.DAO_SEARCH_ERROR);
				} finally {
					try {
						if (con != null) {
							con.close();
						}
					} catch (SQLException e) {
						String message = "数据库连接断开失败！";
						logger.error(message, e);
					}
				}
			}
		}
		return this.keyGenerator.getUID();
	}
}
